/**
 * Copyright 2019-2022 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "compatible/AiTensor.h"

#include <map>

#include "tensor/aipp_para.h"
#include "tensor/image_tensor_buffer.h"
#include "util/base_types.h"
#include "framework/infra/log/log.h"
#include "infra/base/securestl.h"
#include "framework/infra/log/log_fmk_interface.h"
#include "AiTensorImpl.h"
#include "infra/base/assertion.h"

namespace hiai {
TensorDimension::TensorDimension()
{
    impl_ = hiai::make_shared_nothrow<TensorDimensionImpl>();
}

TensorDimension::~TensorDimension()
{
}

TensorDimension::TensorDimension(uint32_t number, uint32_t channel, uint32_t height, uint32_t width)
{
    impl_ = hiai::make_shared_nothrow<TensorDimensionImpl>(number, channel, height, width);
}

void TensorDimension::SetNumber(const uint32_t number)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_VOID(impl_);
    impl_->SetNumber(number);
}

uint32_t TensorDimension::GetNumber() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, 0);
    return impl_->GetNumber();
}

void TensorDimension::SetChannel(const uint32_t channel)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_VOID(impl_);
    impl_->SetChannel(channel);
}

uint32_t TensorDimension::GetChannel() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, 0);
    return impl_->GetChannel();
}

void TensorDimension::SetHeight(const uint32_t height)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_VOID(impl_);
    impl_->SetHeight(height);
}

uint32_t TensorDimension::GetHeight() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, 0);
    return impl_->GetHeight();
}

void TensorDimension::SetWidth(const uint32_t width)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_VOID(impl_);
    impl_->SetWidth(width);
}

uint32_t TensorDimension::GetWidth() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, 0);
    return impl_->GetWidth();
}

bool TensorDimension::IsEqual(const TensorDimension& dim)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, false);
    HIAI_EXPECT_NOT_NULL_R(dim.impl_, false);
    return impl_->IsEqual(dim.impl_->GetNumber(), dim.impl_->GetChannel(), dim.impl_->GetHeight(),
        dim.impl_->GetWidth());
}

AiTensor::AiTensor()
{
    impl_ = hiai::make_shared_nothrow<AiTensorImpl>();
    HIAI_EXPECT_NOT_NULL_VOID(impl_);
}

AiTensor::~AiTensor()
{
    if (impl_ != nullptr) {
        impl_.reset();
        impl_ = nullptr;
    }
}

AIStatus AiTensor::Init(const TensorDimension* dim, HIAI_DataType pdataType)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->Init(dim, pdataType);
}

AIStatus AiTensor::Init(const void* data, const TensorDimension* dim, HIAI_DataType pdataType)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->Init(data, dim, pdataType);
}

AIStatus AiTensor::Init(const TensorDimension* dim)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->Init(dim);
}

AIStatus AiTensor::Init(const NativeHandle& handle, const TensorDimension* dim, HIAI_DataType pdataType)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->Init(handle, dim, pdataType);
}

AIStatus AiTensor::Init(uint32_t number, uint32_t height, uint32_t width, AiTensorImage_Format format)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->Init(number, height, width, format);
}

uint32_t AiTensor::GetSize() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, 0);
    return impl_->GetSize();
}

void* AiTensor::GetBuffer() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, nullptr);
    return impl_->GetBuffer();
}

void* AiTensor::GetTensorBuffer() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, nullptr);
    return impl_->GetTensorBuffer();
}

AIStatus AiTensor::SetTensorDimension(const TensorDimension* dim)
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, AI_FAILED);
    return impl_->SetTensorDimension(dim);
}

TensorDimension AiTensor::GetTensorDimension() const
{
    H_LOG_INTERFACE_FILTER(ITF_COUNT);
    HIAI_EXPECT_NOT_NULL_R(impl_, TensorDimension());
    return impl_->GetTensorDimension();
}

} // namespace hiai
